"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EntityDynamicQuery = void 0;
exports.Entity = Entity;
exports.TableField = TableField;
exports.Parent = Parent;
const dynamicQuery_1 = require("./dynamicQuery");
const common_1 = require("./common");
require("reflect-metadata");
// 定义元数据键常量
const METADATA_KEYS = {
    TABLE: 'table',
    IGNORE_FIELDS: 'ignoreField',
    PARENT_CONFIG: 'parent'
};
/**
 * 实体动态查询类，用于特定实体的数据库操作
 */
class EntityDynamicQuery extends dynamicQuery_1.DynamicQuery {
    constructor(client, entityClass, options = {}) {
        const tableName = Reflect.getMetadata(METADATA_KEYS.TABLE, entityClass.prototype);
        if (!tableName) {
            throw new Error(`Entity class ${entityClass.name} is missing @Entity decorator`);
        }
        const tableConfig = new common_1.TableConfig(tableName, []);
        super(tableConfig, client, options);
        this.entityClass = entityClass;
        this.parentConfigs = this.getMetadata(entityClass.prototype, METADATA_KEYS.PARENT_CONFIG, []);
        this.entityFields = this.getEntityFields(this.parentConfigs);
        tableConfig.columnSet = this.entityFields;
        tableConfig.parents = this.parentConfigs;
    }
    /**
     * 获取实体字段列表
     */
    getEntityFields(parents) {
        const parentObjects = parents.map(value => value.parentObject);
        // 显式声明类型，避免推断为 never[]
        const ignoreFields = this.getMetadata(this.entityClass.prototype, METADATA_KEYS.IGNORE_FIELDS, []);
        ignoreFields.push(...parentObjects);
        return Reflect.ownKeys(new this.entityClass())
            .filter(key => typeof key === 'string' && !ignoreFields.includes(key));
    }
    /**
     * 获取元数据，如果不存在则返回默认值
     */
    getMetadata(target, metadataKey, defaultValue) {
        const metadata = Reflect.getMetadata(metadataKey, target);
        return metadata !== undefined ? metadata : defaultValue;
    }
    /**
     * 将数据库结果转换为实体对象
     */
    toEntity(data) {
        return data ? (0, common_1.anyToEntity)(data, () => new this.entityClass()) : null;
    }
    /**
     * 将数据库结果数组转换为实体对象数组
     */
    toEntities(data) {
        return data ? (0, common_1.anyToEntities)(data, () => new this.entityClass()) : [];
    }
    /**
     * 查找所有匹配条件的实体
     */
    async findAll(query = {}, transaction, page = {}) {
        const results = await super.findAll(query, transaction, page);
        return this.toEntities(results);
    }
    /**
     * 查找第一个匹配条件的实体
     */
    async findOne(query = {}, transaction) {
        const result = await super.findOne(query, transaction);
        return this.toEntity(result);
    }
    /**
     * 分页查询实体
     */
    async find(query, page, transaction) {
        await super.find(query, page, transaction);
        page.content = this.toEntities(page.content);
    }
    /**
     * 导航分页查询实体
     */
    async navigationFind(query = {}, page, transaction) {
        await super.navigationFind(query, page, transaction);
        page.content = this.toEntities(page.content);
    }
    /**
     * 通过SQL分页查询实体
     */
    async findBySql({ selectSql, formWhereSql, orderBySql = "" }, page, transaction) {
        await super.findBySql({ countInSql: null, selectSql, formWhereSql, orderBySql }, page, transaction);
        page.content = this.toEntities(page.content);
    }
    /**
     * 导航查询所有匹配条件的实体
     */
    async navigationFindAll(query = {}, page, transaction) {
        const results = await super.navigationFindAll(query, page, transaction);
        return this.toEntities(results);
    }
    /**
     * 导航查询第一个匹配条件的实体
     */
    async navigationFindOne(query = {}, transaction) {
        const result = await super.navigationFindOne(query, transaction);
        return this.toEntity(result);
    }
    /**
     * 创建新实体
     */
    async create(data = {}, hasReturn = true, transaction) {
        const result = await super.create(data, hasReturn, transaction);
        return this.toEntity(result);
    }
    /**
     * 保存实体（有则更新，无则创建）
     */
    async save(data = {}, transaction) {
        const result = await super.save(data, transaction);
        return this.toEntity(result);
    }
    /**
     * 批量保存实体
     */
    async saveAll(entities = [], transaction) {
        const results = await super.saveAll(entities, transaction);
        return this.toEntities(results);
    }
    /**
     * 更新实体
     */
    async update(data, isAllUpdate = true, transaction) {
        const result = await super.update(data, isAllUpdate, transaction);
        return this.toEntity(result);
    }
    /**
     * 根据ID批量更新实体
     */
    async updateByIds(data, ids = [], isAllUpdate = true, transaction) {
        const results = await super.updateByIds(data, ids, isAllUpdate, transaction);
        return this.toEntities(results);
    }
    /**
     * 根据查询条件更新实体并返回结果
     */
    async updateByQueryWithResult(data, query, isAllUpdate = true, transaction) {
        const results = await super.updateByQueryWithResult(data, query, isAllUpdate, transaction);
        return this.toEntities(results);
    }
    /**
     * 根据ID查找实体
     */
    async findById(id, transaction) {
        const result = await super.findById(id, transaction);
        return this.toEntity(result);
    }
    /**
     * 根据ID列表批量查找实体
     */
    async findByIds(ids = [], transaction) {
        const results = await super.findByIds(ids, transaction);
        return this.toEntities(results);
    }
    /**
     * 填充父对象
     */
    async fillParentObject(content, transaction) {
        await super.fillParentObject(content, transaction);
        for (const parent of this.parentConfigs) {
            if (!parent.parentClass)
                continue;
            content.forEach(entity => {
                if (entity[parent.parentObject]) {
                    entity[parent.parentObject] = (0, common_1.anyToEntity)(entity[parent.parentObject], () => new parent.parentClass());
                }
            });
        }
    }
}
exports.EntityDynamicQuery = EntityDynamicQuery;
/**
 * 实体装饰器，用于标记实体类并指定对应的数据库表名
 */
function Entity(tableName) {
    return (target) => {
        if (!tableName) {
            throw new Error('Table name is required for @Entity decorator');
        }
        Reflect.defineMetadata(METADATA_KEYS.TABLE, tableName, target.prototype);
    };
}
/**
 * 表字段装饰器，用于标记实体字段属性
 */
function TableField(config = { ignore: false }) {
    return (target, propertyKey) => {
        if (config.parentConfig) {
            setParentConfig(target, config.parentConfig, propertyKey);
        }
        const ignoreFields = getMetadata(target, METADATA_KEYS.IGNORE_FIELDS, []);
        ignoreFields.push(propertyKey);
        Reflect.defineMetadata(METADATA_KEYS.IGNORE_FIELDS, ignoreFields, target);
    };
}
/**
 * 父对象装饰器，用于标记实体中的父对象属性
 */
function Parent(config) {
    return (target, propertyKey) => {
        setParentConfig(target, config, propertyKey);
    };
}
/**
 * 设置父对象配置元数据
 */
function setParentConfig(target, config, propertyKey) {
    const parentConfigs = getMetadata(target, METADATA_KEYS.PARENT_CONFIG, []);
    let parentTable;
    let parentIdName;
    if (config.parentClass) {
        parentTable = Reflect.getMetadata(METADATA_KEYS.TABLE, config.parentClass.prototype);
        if (!parentTable) {
            throw new Error(`Parent class ${config.parentClass.name} is missing @Entity decorator`);
        }
        parentIdName = 'id';
    }
    else {
        if (!config.parentTable || !config.parentIdName) {
            throw new Error('Either parentClass or both parentTable and parentIdName must be provided');
        }
        parentTable = config.parentTable;
        parentIdName = config.parentIdName;
    }
    const parentConfig = {
        parentObject: propertyKey,
        parentTable,
        parentIdName,
        parentId: config.parentId,
        parentClass: config.parentClass
    };
    parentConfigs.push(parentConfig);
    Reflect.defineMetadata(METADATA_KEYS.PARENT_CONFIG, parentConfigs, target);
}
/**
 * 获取元数据，如果不存在则返回默认值
 */
function getMetadata(target, metadataKey, defaultValue) {
    const metadata = Reflect.getMetadata(metadataKey, target);
    return metadata !== undefined ? metadata : defaultValue;
}
